FBL.ns(function() { with (FBL) {

	Components.utils.import("resource://firebug/firebug-trace-service.js");
	
	var FBTrace = traceConsoleService.getTracer("extensions.firebug");
	var panelName = "AtsTracer";
	var atsPanel = null;
	var	tableData = { rows: [ ] };
	var orderNewerFirst = true;

	var template = domplate(
	{
	  table:
		  TABLE({border: "1", cellpadding: "2", cellspacing: "0", width: "100%"},
			THEAD(
			
			TR(
				TD(B("time")), TD(B("url")), TD(B("proxy")), TD(B("cache-lookup")), TD(B("server-info")), TD(B("cache-fill"))
			)),
			TBODY(
			  FOR("row", "$data.rows",
				  TR(
					  FOR("value", "$row.values",
						  TD({class: "myTableCell"},
							  "$value")
					  )
				  )
			  )
			)
		  ),
	});		
	
	function getProxyName(value) {
		var arr = value.split(" ");
		arr = arr[1].split(" ");
		return arr[0];
	}
	
	function extractViaCodes(value) {
		var arr = value.split("[");
		arr = arr[1].split("]");
		return arr[0];
	}
	
	function getCodeValue(codes, codelabel) {
		codeIndex = codes.indexOf(codelabel);
		return codes.charAt(codeIndex + 1);
	}	
	
	function getCacheLookupDescription(viaCode){
	
	/*
		A	 in cache, not acceptable (a cache "MISS")
		H	 in cache, fresh (a cache "HIT")
		M	 miss (a cache "MISS")
		S	 in cache, stale (a cache "MISS")
		blank	 no cache lookup performed			
	*/
		var codeValue = getCodeValue(viaCode, 'c');
		switch(codeValue)
		{
			case 'A':
				return 'in cache, not acceptable (a cache "MISS")';
			case 'H':
				return 'in cache, fresh (a cache "HIT")';
			case 'M':
				return 'miss (a cache "MISS")';
			case 'S':
				return 'in cache, stale (a cache "MISS")';
			case ' ':
				return 'no cache lookup performed';
		}
		
		return codeValue + '?';
	}
	
	function getServerInfoDescription(viaCode){
	
	/*
		E	 error in response
		N	 not-modified
		S	 served
		blank	 no server connection needed	
	*/
		var codeValue = getCodeValue(viaCode, 's');
		switch(codeValue)
		{
			case 'E':
				return 'error in response';
			case 'N':
				return 'not-modified';
			case 'S':
				return 'served';
			case ' ':
				return 'no server connection needed';
		}
		
		return codeValue + '?';
	}

	function getCacheFillDescription(viaCode){
	
	/*
		D	 cached copy deleted
		U	 updated old cache copy
		W	 written into cache (new copy)
		blank	 no cache write performed
	*/
		var codeValue = getCodeValue(viaCode, 'f');
		switch(codeValue)
		{
			case 'D':
				return 'cached copy deleted';
			case 'U':
				return 'updated old cache copy';
			case 'W':
				return 'written into cache (new copy)';
			case ' ':
				return 'no cache write performed';
		}
		
		return codeValue + '?';
	}
			
	function ISODateString(d){
		function pad(n){return n<10 ? '0'+n : n}
		return d.getUTCFullYear()+'-'
				+ pad(d.getUTCMonth()+1)+'-'
				+ pad(d.getUTCDate())+'T'
				+ pad(d.getUTCHours())+':'
				+ pad(d.getUTCMinutes())+':'
				+ pad(d.getUTCSeconds())+'Z'}			
	
	function outputTable(){
		var parentNode = atsPanel.panelNode;
		template.table.replace({data: tableData}, parentNode, template);	
	}
	
	Firebug.AtsTracerModel = extend(Firebug.Module,
	{
		showPanel: function(browser, panel) {
			var isAtsPanel = panel && panel.name == panelName;			
			var atsButtons = browser.chrome.$("fbAtsTracerButtons");
			FBTrace.sysout('panelName',panelName);
			FBTrace.sysout('hwButtons',atsButtons);			
			collapse(atsButtons, !isAtsPanel);
		},
		onReverseOrderButton: function() {
			orderNewerFirst = !orderNewerFirst;
			FBTrace.sysout('current orderNewerFirst: ' + String(orderNewerFirst));
		
			tableData.rows.reverse();			
			outputTable();
		},			
		onClearButton: function() {			
			tableData.rows = new Array();
			outputTable();		
		}
	});

function AtsTracerPanel() {}
	AtsTracerPanel.prototype = extend(Firebug.Panel,
	{
		name: panelName,
		title: "ats-tracer",
		
		initialize: function() {
		
			Firebug.Panel.initialize.apply(this, arguments);
			Firebug.NetMonitor.addListener(this);
			atsPanel = this;
				
			var parentNode = this.panelNode;
			
			var myListener = {
				onResponse: function(context, file) 
				{					
					//FBTrace.sysout("onResponse", file);
					
					
					var via = '';					
					for (var i = 0; i < file.responseHeaders.length; i++) { 						
						if(file.responseHeaders[i].name == 'Via'){
							via = file.responseHeaders[i].value;
						}						
					}
					
					var url = file.href;
					if(url.length > 25) {
						shorturl = url.substring(0,24)+"...";
					}
					var urlitem =  shorturl;//'<a href="'+url+'" class="tooltip" title="'+url+'" >'+shorturl+'</a>';
					
					var viaCode = extractViaCodes(via);
					
					
					
					var valuesObj = {values: [  ISODateString(new Date(file.startTime)), 
													urlitem, 
													getProxyName(via), 
													getCacheLookupDescription(viaCode), 
													getServerInfoDescription(viaCode), 
													getCacheFillDescription(viaCode)]};
					if (orderNewerFirst) {
						tableData.rows.unshift(valuesObj);
					} else {
						tableData.rows.push(valuesObj);
					}
					
					outputTable();
					
				}
			}
			
			Firebug.NetMonitor.addListener(myListener);
		
		},
	
	});

	Firebug.registerModule(Firebug.AtsTracerModel);
	Firebug.registerPanel(AtsTracerPanel);

}});